// Fill out your copyright notice in the Description page of Project Settings.


#include "Character/StarrySkyCharacterBase.h"

#include "AbilitySystemComponent.h"
#include "StarrySkyGameplayTags.h"
#include "AbilitySystem/StarrySkyAbilitySystemComponent.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "StarrySky/StarrySky.h"

AStarrySkyCharacterBase::AStarrySkyCharacterBase()
{
	PrimaryActorTick.bCanEverTick = false;
	//创建武器对象
	Weapon = CreateDefaultSubobject<USkeletalMeshComponent>("Weapon");
	//将武器挂载到角色的武器插槽
	Weapon->SetupAttachment(GetMesh(), FName("WeaponHandSocket"));
	//去掉武器组件的碰撞检测
	Weapon->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	//设置网格体和胶囊体对摄像机的碰撞为忽略
	GetCapsuleComponent()->SetCollisionResponseToChannel(ECC_Camera,ECR_Ignore);
	GetMesh()->SetCollisionResponseToChannel(ECC_Camera,ECR_Ignore);
	//胶囊体设置不生成重叠事件
	GetCapsuleComponent()->SetGenerateOverlapEvents(false);

	//设置对抛射物的碰撞检测为重叠,这里不能设置胶囊体的碰撞为忽略因为会导致火球直接碰撞到胶囊体
	GetMesh()->SetCollisionResponseToChannel(ECC_Projectile,ECR_Overlap);
	GetMesh()->SetGenerateOverlapEvents(true);
}

UAbilitySystemComponent* AStarrySkyCharacterBase::GetAbilitySystemComponent() const
{
	return AbilitySystemComponent;
}

FVector AStarrySkyCharacterBase::GetCombatSocketLocation_Implementation(const FGameplayTag& MontageTag)
{
	const FStarrySkyGameplayTags& GameplayTags = FStarrySkyGameplayTags::Get();
	//获取攻击动画游戏标签的不同类型获取正确的攻击位置的插槽
	if (MontageTag.MatchesTagExact(GameplayTags.CombatSocket_Weapon))
	{
		//避免没有设置武器的检查
		check(Weapon);
		return Weapon->GetSocketLocation(WeaponTipSocketName);
	}
	//左手的攻击插槽位置
	/**
	if (MontageTag.MatchesTagExact(GameplayTags.CombatSocket_LeftHand))
	{
		//角色的静态网格中获取左手插槽位置
		check(GetMesh());
		return GetMesh()->GetSocketLocation(LeftHandSocketName);
	}
	//右手的攻击插槽位置
	if (MontageTag.MatchesTagExact(GameplayTags.CombatSocket_RightHand))
	{
		//角色的静态网格中获取右手插槽位置
		check(GetMesh());
		return GetMesh()->GetSocketLocation(RightHandSocketName);
	}
	//获取尾部攻击插槽位置
	if (MontageTag.MatchesTagExact(GameplayTags.CombatSocket_Tail))
	{
		//角色的静态网格中获取尾部插槽位置
		check(GetMesh());
		return GetMesh()->GetSocketLocation(TailSocketName);
	}
	*/
	return FVector();
}

void AStarrySkyCharacterBase::BeginPlay()
{
	Super::BeginPlay();
	GetCharacterMovement()->MaxWalkSpeed=BaseWalkSpeed;
}

void AStarrySkyCharacterBase::InitAbilityActorInfo()
{
}

void AStarrySkyCharacterBase::ApplyEffectToSelf(TSubclassOf<UGameplayEffect> GameplayEffectClass, float Level) const
{
	check(IsValid(GetAbilitySystemComponent()));
	check(GameplayEffectClass);
	//创建效果的上下文句柄
	FGameplayEffectContextHandle EffectContext = GetAbilitySystemComponent()->MakeEffectContext();
	EffectContext.AddSourceObject(this);
	//创建效果规则
	const FGameplayEffectSpecHandle DefaultEffectHandle = GetAbilitySystemComponent()->MakeOutgoingSpec(GameplayEffectClass,Level,EffectContext);
	//应用属性效果类
	GetAbilitySystemComponent()->ApplyGameplayEffectSpecToTarget(*DefaultEffectHandle.Data.Get(),GetAbilitySystemComponent());
}

void AStarrySkyCharacterBase::InitializeDefaultAttributes() const
{
	ApplyEffectToSelf(DefaultPrimaryAttributes,1.f);
	ApplyEffectToSelf(DefaultSecondaryAttributes,1.f);
	ApplyEffectToSelf(DefaultVitalAttributes,1.f);
}

void AStarrySkyCharacterBase::AddCharacterAbilities()
{
	UStarrySkyAbilitySystemComponent* AuraASC = CastChecked<UStarrySkyAbilitySystemComponent>(GetAbilitySystemComponent());
	//在服务器上执行所有要先检查权限
	if(!HasAuthority()) return;
	AuraASC->AddCharacterAbilities(StartupAbilities);//加载主动能力
}

